﻿using System;
using System.Collections.Generic;
using System.Linq;
using ZhCun.WebCommon.DBModels;
using ZhCun.Utils.Helpers;
using System.Threading.Tasks;

namespace ZhCun.WebCommon.AL
{
    public class ALUserBase : BaseAL
    {
        public ALUserBase()
        { }

        /// <summary>
        /// 用户登录
        /// </summary>
        bool Login(string token, string loginName, string loginPwd, int expiresMinute, int loginMode, string clientSN, out string msg)
        {
            if (token.IsEmpty() && StringHelper.IsNullOrWhiteSpace(loginName, loginPwd))
            {
                msg = "用户名或密码不能为空";
                return false;
            }
            if (expiresMinute <= 0)
            {
                msg = "配置参数错误";
                return false;
            }
            P_UserLogin p = new P_UserLogin();
            p.Arg_LoginToken = token;
            p.Arg_LoginName = loginName;
            p.Arg_LoginPwd = loginPwd;
            p.Arg_LoginClientSN = clientSN;
            p.Arg_LoginExpiresMinute = expiresMinute;
            p.Arg_LoginMode = loginMode;
            var r = DB.ExecProcedure(p);
            var tokens = r.ToList<TSysLoginToken>();
            msg = p.OutMsg;
            if (p.OutCode == 0)
            {
                bool hasInvalidToken = false;
                foreach (var item in tokens)
                {
                    if (item.LoginState)
                    {
                        LoginStateCache.Set(item);
                        SetLoginState(item);
                    }
                    else
                    {
                        LoginStateCache.Remove(item.LoginToken);
                        hasInvalidToken = true;
                    }
                }
                if (hasInvalidToken)
                {
                    //删除所有过期的Token和无效的Token
                    DB.Delete<TSysLoginToken>(s => s.LoginState == false || s.LoginExpiresTime < DateTime.Now);
                }
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 用户名密码登录
        /// </summary>
        public bool Login(string loginName, string loginPwd, int expiresMinute, int loginMode, string clientSN, out string msg)
        {
            return Login(null, loginName, loginPwd, expiresMinute, loginMode, clientSN, out msg);
        }
        /// <summary>
        /// token登录
        /// </summary>
        public bool Login(string token, int expiresMinute, int loginMode, out string msg)
        {
            return Login(token, null, null, expiresMinute, loginMode, null, out msg);
        }

        /// <summary>
        /// 获取所有在有效期的登录用户信息
        /// </summary>
        public List<TSysLoginToken> GetValidToken()
        {
            //清除过期的token
            DB.Delete<TSysLoginToken>(s => s.LoginExpiresTime < DateTime.Now);
            var userList = DB.Query<TSysLoginToken>(s => s.LoginExpiresTime > DateTime.Now).ToList(true);
            WriteLog("载入有效Token数：" + userList.Count);
            return userList;
        }
        /// <summary>
        /// 登录退出
        /// </summary>
        public bool LoginOut()
        {
            LoginStateCache.Remove(LoginUser.LoginToken);
            var delResult = DB.Delete<TSysLoginToken>(s => s.LoginToken == LoginUser.LoginToken);
            return delResult.RowCount == 1;
        }

        public bool ChangeUserInfo(TSysUser user, out string errMsg)
        {
            if (!user.UserName.IsLenRange(3, 20))
            {
                errMsg = "用户名格式不正确";
                return false;
            }
            if (!user.MobileNumber.IsLenRange(7, 11))
            {
                errMsg = "号码格式不正确";
                return false;
            }
            if (DB.QueryExist<TSysUser>(s => s.LoginName == user.LoginName && s.Id != user.Id))
            {
                errMsg = "登录名已存在";
                return false;
            }
            if (DB.QueryExist<TSysUser>(s => s.MobileNumber == user.MobileNumber && s.Id != user.Id))
            {
                errMsg = "手机号已存在";
                return false;
            }
            user.ClearChangedState();
            user.SetFieldChanged(TSysUser.CNUserName, TSysUser.CNMobileNumber);            
            LoginUser.UserName = user.UserName;
            LoginUser.MobileNumber = user.MobileNumber;
            var r = DB.Update(user, s => s.Id == LoginUser.LoginUserId );
            if (r.RowCount == 1)
            {
                errMsg = "修改用户信息成功";
                return true;
            }
            else
            {
                errMsg = "修改用户信息失败";
                return false;
            }
        }

        ///// <summary>
        ///// 保存用户信息（注册新增或修改）
        ///// </summary>
        //public bool SaveUserInfo(TSysUser user, string loginHost, string clientSN, out string errMsg)
        //{
        //    if (StringHelper.IsNullOrWhiteSpace(user.LoginName, user.UserName, user.MobileNumber))
        //    {
        //        errMsg = "必要字段不能为空。";
        //        return false;
        //    }
        //    if (user.IsChangeField(TSysUser.CNLoginPwd) && string.IsNullOrWhiteSpace(user.LoginPwd))
        //    {
        //        errMsg = "密码不能为空";
        //        return false;
        //    }
        //    if (DB.QueryExist<TSysUser>(s => s.LoginName == user.LoginName && s.Id != user.Id))
        //    {
        //        errMsg = "登录名已存在";
        //        return false;
        //    }
        //    if (DB.QueryExist<TSysUser>(s => s.UserName == user.UserName && s.Id != user.Id))
        //    {
        //        errMsg = "用户名已存在";
        //        return false;
        //    }
        //    if (DB.QueryExist<TSysUser>(s => s.MobileNumber == user.MobileNumber && s.Id != user.Id))
        //    {
        //        errMsg = "手机号已存在";
        //        return false;
        //    }

        //    if (string.IsNullOrWhiteSpace(user.Id))
        //    {
        //        var token = new TSysLoginToken();
        //        token.LoginHost = loginHost;
        //        token.LoginClientSN = clientSN;
        //        SetLoginState(token);
        //        user.Id = GetGuid();
        //        DB.Insert(user);
        //        errMsg = "用户注册成功";

        //        P_UserRegister p = new P_UserRegister();
        //        p.LoginHost = loginHost;
        //        p.LoginName = user.LoginName;
        //        p.MobileNumber = user.MobileNumber;
        //        p.UserName = user.UserName;

        //        return true;
        //    }
        //    else
        //    {
        //        user.ClearChangedState();
        //        user.SetFieldChanged(TSysUser.CNLoginName, TSysUser.CNUserName, TSysUser.CNMobileNumber);
        //        LoginUser.LoginName = user.LoginName;
        //        LoginUser.UserName = user.UserName;
        //        LoginUser.MobileNumber = user.MobileNumber;
        //        DB.Update(user, s => s.Id == user.Id);
        //        errMsg = "修改用户信息成功";
        //        return true;
        //    }
        //}
        /// <summary>
        /// 修改当前用户密码
        /// </summary>
        public bool ChangePassword(string oldPwd, string newPwd, out string errMsg)
        {
            TSysUser user = new TSysUser();
            user.LoginPwd = newPwd;
            var r = DB.Update(user, s => s.Id == LoginUser.LoginUserId && s.LoginPwd == oldPwd);
            if (r.RowCount == 1)
            {
                errMsg = "密码修改成功";
                return true;
            }
            errMsg = "密码修改失败";
            return false;
        }
        /// <summary>
        /// 刷新当前token的过期时间
        /// </summary>
        public bool RefreshToken(string token, DateTime? expiresTime = null)
        {
            TSysLoginToken tokenObj = DB.Query<TSysLoginToken>(s => s.LoginToken == token).ToEntity();
            if (tokenObj == null)
            {
                return false;
            }
            else
            {
                tokenObj.LastTime = GetNowTime();
                if (expiresTime == null)
                {
                    expiresTime = DateTime.Now.AddMinutes(tokenObj.LoginExpiresMinute);
                }
                tokenObj.LoginExpiresTime = expiresTime.Value;
                DB.Update(tokenObj);
                return true;
            }

           
        }

        public async void RefreshTokenAsync(string token, DateTime expiresTime)
        {
            //return //Task<bool> 
            //await
            //Task.Run(() => { return RefreshToken(token, expiresTime); });
            await
            Task.Run(() => { return RefreshToken(token, expiresTime); });
        }
    }
}